package com.cloud.common.client.spring;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;

import com.cloud.common.client.anno.FeignClient;
import com.cloud.common.tools.JsonHelper;
import com.cloud.common.tools.RestClientUtil;

public class FeignClientProxy implements InvocationHandler {
	private Class<?> interfaceClass;
	private String cloudRegisteryAddress;
	public FeignClientProxy(Class<?> interfaceClass,String cloudRegisteryAddress) {
		super();
		this.interfaceClass = interfaceClass;
		this.cloudRegisteryAddress = cloudRegisteryAddress;
	}

	@SuppressWarnings("unchecked")
	public <T> T getMapper() {
		return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
				new Class<?>[] { interfaceClass },this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		PostMapping postMapping = method.getDeclaredAnnotation(PostMapping.class);
		if(postMapping!=null) {
			FeignClient FeignClient= interfaceClass.getAnnotation(FeignClient.class);
			try {
				String path = cloudRegisteryAddress+"/fetch";
				String addr = RestClientUtil.httpClientByGet(path+"?appName="+FeignClient.value(),  String.class);
				System.out.println("remote addr="+addr+postMapping.value()[0]+",args="+JsonHelper.INSTANCE.toJson(args));
				Class<?> returnType=Class.forName(method.getReturnType().getTypeName());
				MultiValueMap<String, Object> param = new LinkedMultiValueMap<String, Object>();
				Map<String, String> map = new HashMap<String, String>(0);
				map = BeanUtils.describe(args[0]);
				for (Entry<String, String> object : map.entrySet()) {
					param.add(object.getKey(),object.getValue());
				}
				return  RestClientUtil.httpClientByPost(addr+postMapping.value()[0], param, returnType,MediaType.APPLICATION_FORM_URLENCODED);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}

}
